`include "include/CacheConfig.sv"
`include "include/cpu_defines.sv"
module mycpu_top(
    input logic           [5:0] ext_int,
    input logic           aclk,
    input logic           aresetn,

	//axi
    //ar
    output [3 :0] arid         ,
    output [31:0] araddr       ,
    output [7 :0] arlen        ,
    output [2 :0] arsize       ,
    output [1 :0] arburst      ,
    output [1 :0] arlock        ,
    output [3 :0] arcache      ,
    output [2 :0] arprot       ,
    output        arvalid      ,
    input         arready      ,
    //r           
    input  [3 :0] rid          ,
    input  [31:0] rdata        ,
    input  [1 :0] rresp        ,
    input         rlast        ,
    input         rvalid       ,
    output        rready       ,
    //aw          
    output [3 :0] awid         ,
    output [31:0] awaddr       ,
    output [7 :0] awlen        ,
    output [2 :0] awsize       ,
    output [1 :0] awburst      ,
    output [1 :0] awlock       ,
    output [3 :0] awcache      ,
    output [2 :0] awprot       ,
    output        awvalid      ,
    input         awready      ,
    //w          
    output [3 :0] wid          ,
    output [31:0] wdata        ,
    output [3 :0] wstrb        ,
    output        wlast        ,
    output        wvalid       ,
    input         wready       ,
    //b           
    input  [3 :0] bid          ,
    input  [1 :0] bresp        ,
    input         bvalid       ,
    output        bready       ,
	output logic[31: 0]           	debug_retire1_pc,
	output logic [3: 0]           	debug_retire1_rf_wen,
	output logic [4: 0] 		  	debug_retire1_rf_wnum,
	output logic [31: 0]          	debug_retire1_rf_wdata,
	output logic [31: 0] 			debug_retire2_pc,
	output logic [3: 0] 			debug_retire2_rf_wen,
	output logic [4: 0] 			debug_retire2_rf_wnum,
	output logic [31: 0] 			debug_retire2_rf_wdata,
	output logic [31: 0]			debug_cp0_random,
	output logic [31: 0] 			debug_cp0_cause,
	output logic [31: 0]			debug_cp0_count,
	output logic 					debug_int,
	output logic 					debug_commit1,
	output logic 					debug_commit2,
	output logic 					predict_en,
	output logic 					predict_err_en,
	output [31:0] debug_wb_pc  ,
	output        debug_wb_rf_wen,
	output [4: 0] debug_wb_rf_wnum,
	output [31: 0] debug_wb_rf_wdata

);
	logic 		inst_req, inst_wr, icache_clear, clear_accept, inst_conflict, inst_accept, next_inst_req;
	logic before_accept;
	logic [1: 0] inst_size;
	logic [31:0] inst_vaddr, inst_wdata;
	logic [1: 0][31: 0] request_addr;
	logic [31:0] inst_paddr, next_inst_vaddr;
	logic [1: 0][31: 0] inst_rdata;
	logic [1: 0] rdata_valid;
	logic        inst_addr_ok, inst_data_ok;
	logic        data_req, data_wr, data_iuncache, data_duncache, data_write_req;
	logic [1: 0] data_size;
	logic [31:0] data_vaddr, data_wdata, data_rdata;
	logic [31:0] data_paddr;
	logic 		data_addr_ok, data_data_ok, data_waddr_ok, data_wdata_ok, data_success;
	logic denable_miss, uenable_miss;
	logic axi_write_valid;

	logic iop, ivalid, dop, dvalid, dcache_clear;
	logic [3: 0] dwstrb, dwr_wstrb, data_wstrb, data_rwstrb;
	logic [31: 0] dwdata, data_vwaddr, data_addr_mask, data_waddr_mask;
	logic [31: 0] data_pwaddr;
	logic ird_ready, drd_ready, iret_valid, dret_valid, iret_last, dret_last;
	logic [31: 0] iret_data, dret_data;
	logic dwr_ready, dwr_last, dreplace_data_en;
	logic dwb_ready;
	logic iaddr_ok, idata_ok, daddr_ok, ddata_ok;
	logic [31: 0] irdata, drdata;
	logic ird_req, drd_req;
	logic [7: 0] daxi_rd_len;
	logic [31: 0] ird_addr, drd_addr;
	logic dwr_req, dpre_rd_req, data_wuncache;
	logic [31: 0] dwr_addr;
	logic [31: 0] dwr_wdata;
	logic ireplace_en, dreplace_en;
	logic [`ICACHE_TAG+`ICACHE_INDEX-1: 0] ireplace_addr;
	logic [7: 0][31: 0] ireplace_data;
	logic udata_success, urd_ok;
	logic write_aceept;
	logic direct_accept;
	logic icache_tlb_valid;
	logic [7: 0][31: 0] direct_data;
	logic [`DCACHE_TAG-1: 0] data_write_ptag, vwtag, pwtag, isearch_tag, dsearch_tag;

	logic axi_rd_ready, axi_ret_valid, axi_ret_last, axi_rd_req;
	logic [7: 0] axi_rd_len;
	logic [31: 0] axi_ret_data;
	logic daxi_rd_ready, daxi_ret_valid, daxi_ret_last, daxi_rd_req;
	logic [31: 0] daxi_ret_data;
	logic [`DCACHE_TAG+`DCACHE_INDEX-1: 0] dreplace_addr;
	logic [7: 0][31: 0] dreplace_data;

	logic mshr_data_valid;
	logic [`READ_BUFFER_WIDTH-1: 0] mshr_queue_index;
	logic [31: 0] mshr_fill_data;

	logic [`READ_BUFFER_WIDTH-1: 0] data_issue_queue_index, read_queue_index;
	logic data_enable_miss, data_abandon_lookup, write_accept;

	logic ucache_valid, uncache_full, ucache_data_ok;
	logic uncache_req, uncache_wr;
	logic [3: 0] uncache_wstrb;
	logic [`READ_BUFFER_WIDTH-1: 0] uncache_queue_index;
	logic [31: 0] uncache_addr, uncache_data;
	logic [`READ_BUFFER_WIDTH-1: 0] ucache_issue_queue_index;
	logic uaxi_wr_ok, ucache_data_rcv;
	logic uaxi_ret_last, uaxi_rd_req, uaxi_wr_req, uwr_end;
	logic [31: 0] ucache_rdata;
	logic [31: 0] uaxi_addr;
	logic [31: 0] uaxi_ret_data, uaxi_wr_data;
	logic [3: 0] uaxi_wstrb;
	logic [1: 0] uaxi_size, uaxi_wr_size;
	logic next_rdata_req, next_wdata_req;
	logic [31: 0] next_vraddr, next_vwaddr, next_wdata;
	logic [`READ_BUFFER_WIDTH-1: 0] next_issue_queue_index;
	logic [3: 0] next_wstrb, next_rwstrb;
	logic kseg0_uncache;

	logic iuncache_en, iuncache_data_ok, iuncache_busy, iuncache_req, iurd_ok, iuret_valid;
	logic [31: 0] iuncache_addr, iurd_addr, iuret_data;
	logic [1: 0][31: 0] iuncache_data;
	logic [1: 0] iuncache_data_valid;
	logic [3: 0] iurd_len;
	logic iuret_last;

	logic cp0_tlb_inst_en;
	logic tlb_iuncache, tlb_druncache, tlb_dwuncache;
	logic inst_tlb_refill, inst_tlb_invalid;
	logic rdata_tlb_refill, rdata_tlb_invalid, wdata_tlb_refill, wdata_tlb_invalid, data_tlb_modify;

	logic lookup_relavant;
	logic [`READ_BUFFER_WIDTH-1: 0] relavant_queue_index;
	logic [31: 0] lookup_relavant_data;

	logic long_data_ok;
	logic [`READ_BUFFER_WIDTH-1: 0] long_queue_index;
	logic [31: 0] long_data;

	logic icache_ready, dcache_ready, cache_valid;
	logic [4: 0] cacheop;
	logic [31: 0] cache_addr;

	logic replace_enable;
	logic [4: 0] victim_index_bundle_controller;
	logic [4: 0] victim_index_bundle_dcache;

	(* keep = "true" *)
	logic cache_rst_n, icache_rst_n, dcache_rst_n, ucache_rst_n, cpu_rst_n;
	always_ff @(posedge aclk)begin
		icache_rst_n <= aresetn;
		dcache_rst_n <= aresetn;
		ucache_rst_n <= aresetn;
		cache_rst_n <= aresetn;
		cpu_rst_n <= aresetn;
	end

	logic [3: 0]	cp0_tlb_type;
	logic [31:0]	cp0_entry_hi;
	logic [31:0]	cp0_page_mask;
	logic [31:0]	cp0_entry_lo0;
	logic [31:0]	cp0_entry_lo1;
	logic [31:0]	cp0_index;
	logic [31:0]	cp0_random;
	logic [31:0]	cp0_taglo;

	logic [31:0] 	tlb_entry_lo0;
	logic [31:0] 	tlb_entry_lo1;
	logic [31:0] 	tlb_page_mask;
	logic [31:0] 	tlb_entry_hi;
	logic [31:0] 	tlb_index;
	logic 			tlb_tlbp_find;

	cpu_axi_interface _interface(
		.clk      (aclk       ),
    	.resetn   (cache_rst_n    ),   //low active

		.ird_req(axi_rd_req),
		.ird_addr(ird_addr),
		.irdata(axi_ret_data),
		.iret_valid(axi_ret_valid),
		.iret_last(axi_ret_last),
		.ird_ready(axi_rd_ready),
		.axi_rd_len(axi_rd_len),

		.drd_req(daxi_rd_req),
		.drd_addr(drd_addr),
		.drdata(daxi_ret_data),
		.dret_valid(daxi_ret_valid),
		.dret_last(daxi_ret_last),
		.drd_ready(daxi_rd_ready),

		.dwr_req(dwr_req),
		.dwr_addr(dwr_addr),
		.dwr_wdata(dwr_wdata),
		.dwr_ready(dwr_ready),
		.dwr_last(dwr_last),
		.dwb_ready(dwb_ready),

		.urd_req(uaxi_rd_req),
		.urd_addr(uaxi_addr),
		.urd_size(uaxi_size),
		.urdata(uaxi_ret_data),
		.uret_last(uaxi_ret_last),
		.urd_ok(urd_ok),
		
		.uwr_req(uaxi_wr_req),
		.uwr_last(1'b1),
		.uwr_addr(uaxi_addr),
		.uwr_size(uaxi_wr_size),
		.uwr_wdata(uaxi_wr_data),
		.uwr_wstrb(uaxi_wstrb),
		.uwr_ok(uaxi_wr_ok),
		.uwr_end(uwr_end),

		.iu_req(iuncache_req),
		.iurd_addr(iurd_addr),
		.iurd_len(iurd_len),
		.iuret_valid(iuret_valid),
		.iuret_last(iuret_last),
		.iurd_ok(iurd_ok),
		.iuret_data(iuret_data),

		.write_valid(axi_write_valid),

		.arid      (arid      ),
		.araddr    (araddr    ),
		.arlen     (arlen     ),
		.arsize    (arsize    ),
		.arburst   (arburst   ),
		.arlock    (arlock    ),
		.arcache   (arcache   ),
		.arprot    (arprot    ),
		.arvalid   (arvalid   ),
		.arready   (arready   ),
	
		.rid       (rid       ),
		.rdata     (rdata     ),
		.rresp     (rresp     ),
		.rlast     (rlast     ),
		.rvalid    (rvalid    ),
		.rready    (rready    ),
	
		.awid      (awid      ),
		.awaddr    (awaddr    ),
		.awlen     (awlen     ),
		.awsize    (awsize    ),
		.awburst   (awburst   ),
		.awlock    (awlock    ),
		.awcache   (awcache   ),
		.awprot    (awprot    ),
		.awvalid   (awvalid   ),
		.awready   (awready   ),
    
		.wid       (wid       ),
		.wdata     (wdata     ),
		.wstrb     (wstrb     ),
		.wlast     (wlast     ),
		.wvalid    (wvalid    ),
		.wready    (wready    ),

		.bid       (bid       ),
		.bresp     (bresp     ),
		.bvalid    (bvalid    ),
		.bready    (bready    )
	);

	ICache #(
		.WAY_NUM(`ICACHE_WAY_NUM)
	) icache(
		.cpu_clk(aclk),
		.cpu_rst_n(icache_rst_n),
		.clear(icache_clear),
		.uncache_req(iuncache_en),
		.tlb_exception(inst_tlb_refill | inst_tlb_invalid),
		.valid(inst_req),
		.op(inst_wr),
		.request_size(inst_size),
		.request_head(inst_vaddr[31: 29]),
		.index(inst_vaddr[`ICACHE_INDEX_BUS]),
		.tag((inst_vaddr[`ICACHE_TAG_BUS])),
		.ptag(inst_paddr[`ICACHE_TAG_BUS]),
		.offset(inst_vaddr[`ICACHE_OFFSET-1: 0]),
		.direct_accept(direct_accept),
		.direct_data(direct_data),
		// .rd_ready(ird_ready),
		.ret_valid(iret_valid),
		.ret_last(iret_last),
		.ret_data(irdata),
		.addr_ok(inst_addr_ok),
		.data_ok(inst_data_ok),
		.conflict(inst_conflict),
		.tlb_valid(icache_tlb_valid),
		// .req_accept(inst_accept),
		.rdata(inst_rdata),
		.rdata_valid(rdata_valid),
		.rd_req(ird_req),
		.rd_addr(ird_addr),
		.replace_en(ireplace_en),
		.replace_addr(ireplace_addr),
		.replace_data(ireplace_data),
		.request_addr(request_addr),
		.op_valid(cache_valid && !cacheop[0]),
		.cacheop(cacheop[4: 2]),
		.op_addr(cache_addr),
		.taglo(cp0_taglo),
		.op_ready(icache_ready),
		.search_tag(isearch_tag)
		// .clear_accept(clear_accept)
	);

	ICacheController icache_controller(
		.cpu_clk(aclk),
		.cpu_rst_n(icache_rst_n),
		.rd_req(ird_req),
		.rd_addr(ird_addr),
		.axi_ret_valid(axi_ret_valid),
		.axi_ret_last(axi_ret_last),
		.axi_rd_ready(axi_rd_ready),
		.axi_ret_data(axi_ret_data),
		.axi_rd_req(axi_rd_req),
		.ret_valid(iret_valid),
		.ret_last(iret_last),
		.ret_data(irdata),
		.direct_accept(direct_accept),
		.direct_data(direct_data),
		// .rd_ready(ird_ready),
		.replace_en(ireplace_en),
		.replace_addr(ireplace_addr),
		.replace_data(ireplace_data),
		.axi_rd_len(axi_rd_len)
	);

	DCache #(
		.WAY_NUM(`DCACHE_WAY_NUM),
		.INDEX_SIZE(`DCACHE_INDEX),
		.OFFSET_SIZE(`DCACHE_OFFSET),
		.TAG_SIZE(`DCACHE_TAG)
	) dcache(
		.cpu_clk(aclk),
		.cpu_rst_n(dcache_rst_n),
		.clear(dcache_clear),
		.read_valid(data_req),
		.write_valid(data_write_req),
		.tlb_rexception(rdata_tlb_refill | rdata_tlb_invalid),
		.read_uncache(tlb_druncache),
		.data_abandon_lookup(data_abandon_lookup),
		.issue_queue_index(data_issue_queue_index),
		.enable_miss(data_enable_miss),
		.data_success(data_success),
		.write_accept(write_accept),
		.rindex(data_addr_mask[`DCACHE_INDEX_BUS]),
		.rtag(data_addr_mask[`DCACHE_TAG_BUS]),
		.rptag(data_paddr[`DCACHE_TAG_BUS]),
		.roffset(data_addr_mask[`DCACHE_OFFSET-1: 0]),
		.wtag(data_waddr_mask[`DCACHE_TAG_BUS]),
		.wptag(data_write_ptag),
		.windex(data_waddr_mask[`DCACHE_INDEX_BUS]),
		.woffset(data_waddr_mask[`DCACHE_OFFSET-1: 0]),
		.rwstrb(data_rwstrb),
		.wstrb( data_wstrb),
		.wdata(data_wdata),
		.rd_ready(drd_ready),
		.ret_valid(dret_valid),
		.ret_last(dret_last),
		.ret_data(drdata),
		.wr_ready(dwr_ready),
		.axi_write_valid(axi_write_valid),
		.wr_data_last(dwr_last),
		.addr_ok(data_addr_ok),
		.data_ok(data_data_ok),
		.write_addr_ok(data_waddr_ok),
		.rdata(data_rdata),
		.read_queue_index(read_queue_index),
		.mshr_data_ok(mshr_data_valid),
		.mshr_queue_index(mshr_queue_index),
		.mshr_data(mshr_fill_data),
		.lookup_relavant(lookup_relavant),
		.relavant_queue_index(relavant_queue_index),
		.lookup_relavant_data(lookup_relavant_data),
		.out_enable_miss(denable_miss),
		.pre_rd_req(dpre_rd_req),
		.rd_req(drd_req),
		.rd_addr(drd_addr),
		.wr_req(dwr_req),
		.wr_addr(dwr_addr),
		.wr_wdata(dwr_wdata),
		.replace_en(dreplace_en),
		// .replace_data_en(dreplace_data_en),
		.replace_addr(dreplace_addr),
		.replace_data(dreplace_data),
		.op_valid(cache_valid && cacheop[0]),
		.cacheop(cacheop[4: 2]),
		.op_addr(cache_addr),
		.taglo(cp0_taglo),
		.op_ready(dcache_ready),
		.search_tag(dsearch_tag),
		.replace_enable(replace_enable),
		.out_victim_index_bundle(victim_index_bundle_dcache),
		.victim_index_bundle(victim_index_bundle_controller)
	);

	DCacheController dcache_controller(
		.cpu_clk(aclk),
		.cpu_rst_n(dcache_rst_n),
		.rd_req(drd_req),
		.pre_rd_req(dpre_rd_req),
		.rd_addr(drd_addr),
		.axi_ret_valid(daxi_ret_valid),
		.axi_ret_last(daxi_ret_last),
		.axi_rd_ready(daxi_rd_ready),
		.axi_ret_data(daxi_ret_data),
		.axi_rd_req(daxi_rd_req),
		.ret_valid(dret_valid),
		.ret_last(dret_last),
		.ret_data(drdata),
		.rd_ready(drd_ready),
		.dwb_ready(dwb_ready),
		.replace_en(dreplace_en),
		// .replace_data_en(dreplace_data_en),
		.replace_addr(dreplace_addr),
		.replace_data(dreplace_data),
		.replace_enable(replace_enable),
		.dwr_req(dwr_req),
		.dwr_ready(dwr_ready),
		.victim_index_bundle_i(victim_index_bundle_dcache),
		.victim_index_bundle(victim_index_bundle_controller)
	);

	assign iuncache_en = 1'b0;
	IUncacheBuffer iuncache_buffer(
		.clk(aclk),
		.resetn(ucache_rst_n),
		.clear(icache_clear),
		.en(iuncache_en),
		.addr(next_inst_vaddr),
		.ptag(inst_paddr[`ICACHE_TAG_BUS]),
		.out_en(iuncache_data_ok),
		.rdata(iuncache_data),
		.rdata_valid(iuncache_data_valid),
		.out_addr(iuncache_addr),
		.busy(iuncache_busy),
		.rd_req(iuncache_req),
		.rd_addr(iurd_addr),
		.rd_len(iurd_len),
		.rd_ok(iurd_ok),
		.ret_valid(iuret_valid),
		.ret_last(iuret_last),
		.ret_data(iuret_data)
	);

	assign ucache_data_rcv = ucache_data_ok & ~mshr_data_valid & ~lookup_relavant;
	// assign data_iuncache = next_rdata_req & tlb_druncache & ~dcache_clear & ~(rdata_tlb_invalid | rdata_tlb_invalid);
	// assign data_duncache = data_write_req & data_wuncache;

	// always_ff @(posedge aclk)begin
	// 	before_accept <= inst_accept;
	// 	next_inst_req <= (inst_req & ~iuncache_busy | icache_clear);
	// 	next_rdata_req <= data_req & data_enable_miss & ~dcache_clear & data_addr_ok & ~uread_full;
	// 	next_vraddr <= data_vaddr;
	// 	next_rwstrb <= data_rwstrb;
	// 	next_inst_vaddr <= inst_vaddr;
	// 	next_issue_queue_index <= data_issue_queue_index;
	// end
	UCacheBuffer ucache_buffer(
		.cpu_clk(aclk),
		.cpu_rst_n(ucache_rst_n),
		.clear(dcache_clear),
		.valid(uncache_req),
		.wr(uncache_wr),
		.issue_queue_index(uncache_queue_index),
		.wstrb(uncache_wstrb),
		.addr_i(uncache_addr),
		.data_i(uncache_data),
		.rd_ok(urd_ok),
		.wr_ok(uaxi_wr_ok),
		.ret_last(uaxi_ret_last),
		.ret_data(uaxi_ret_data),
		.data_rcv(ucache_data_rcv),
		.full(uncache_full),
		.wr_end(uwr_end),
		.data_ok(ucache_data_ok),
		.rdata(ucache_rdata),
		.out_issue_queue_index(ucache_issue_queue_index),
		.data_success(udata_success),
		.rd_req(uaxi_rd_req),
		.wr_req(uaxi_wr_req),
		.rd_size(uaxi_size),
		.wr_size(uaxi_wr_size),
		.wr_wstrb(uaxi_wstrb),
		.wr_data(uaxi_wr_data),
		.out_addr(uaxi_addr)
	);

	assign data_addr_mask = data_vaddr;
	assign data_waddr_mask = data_vwaddr;
	always_ff @(posedge aclk)begin
		long_data_ok <= ~dcache_clear & (mshr_data_valid | ucache_data_ok | lookup_relavant);
		long_data <= lookup_relavant ? lookup_relavant_data : mshr_data_valid ? mshr_fill_data : ucache_rdata;
		long_queue_index <= lookup_relavant ? relavant_queue_index : mshr_data_valid ? mshr_queue_index : ucache_issue_queue_index;
	end
    CPUCore cpu_core(
        .clk(aclk),
        .resetn(cpu_rst_n),
        .ext_int(ext_int),
`ifdef CPU_DEBUG
		.debug_retire1_pc(debug_retire1_pc),
		.debug_retire1_rf_wen(debug_retire1_rf_wen),
		.debug_retire1_rf_wnum(debug_retire1_rf_wnum),
		.debug_retire1_rf_wdata(debug_retire1_rf_wdata),
		.debug_retire2_pc(debug_retire2_pc),
		.debug_retire2_rf_wen(debug_retire2_rf_wen),
		.debug_retire2_rf_wnum(debug_retire2_rf_wnum),
		.debug_retire2_rf_wdata(debug_retire2_rf_wdata),
		.debug_cp0_cause(debug_cp0_cause),
		.debug_cp0_random(debug_cp0_random),
		.debug_cp0_count(debug_cp0_count),
		.debug_int(debug_int),
		.debug_commit1(debug_commit1),
		.debug_commit2(debug_commit2),
		.predict_en(predict_en),
		.predict_err_en(predict_err_en),
`endif 

        .inst_req  (inst_req      ),
		.inst_clear(icache_clear  ),
		// .clear_accept(clear_accept),
		.inst_wr   (inst_wr       ),
		.inst_size (inst_size     ),
		.inst_addr (inst_vaddr     ),
		.inst_wdata(inst_wdata    ),
		.inst_rdata(inst_rdata    ),
		.inst_rdata_valid(rdata_valid),
		.inst_addr_ok((inst_addr_ok & ~iuncache_busy)),
		.inst_data_ok(inst_data_ok | iuncache_data_ok),
		.inst_conflict(inst_conflict),
		// .inst_accept(inst_accept | iuncache_en & ~before_accept),
		.inst_request_addr(request_addr),
		.inst_tlb_refill (icache_tlb_valid & inst_tlb_refill),
		.inst_tlb_invalid(icache_tlb_valid & inst_tlb_invalid),
		.rdata_tlb_refill(rdata_tlb_refill),
		.rdata_tlb_invalid(rdata_tlb_invalid),
		.wdata_tlb_refill(wdata_tlb_refill),
		.wdata_tlb_invalid(wdata_tlb_invalid),
		.data_tlb_modify(data_tlb_modify),
		.data_req  (data_req      ),
		.data_clear(dcache_clear),
		.data_write_req(data_write_req),
		.data_write_accept(write_accept),
		.data_abandon_lookup(data_abandon_lookup),
		.data_success(data_success),
		.data_wstrb(data_wstrb    ),
		.data_rwstrb(data_rwstrb),
		.data_addr (data_vaddr     ),
		.data_waddr(data_vwaddr	  ),
		.data_wdata(data_wdata    ),
		.vwtag(vwtag),
		.pwtag(pwtag),
		.prtag(data_paddr[31: 12]),
		.data_runcache(tlb_druncache),
		.data_write_ptag(data_write_ptag),
		
		.data_wuncache(tlb_dwuncache),
		.data_rdata(data_rdata),
		.data_issue_queue_index(data_issue_queue_index),
		.data_enable_miss(data_enable_miss),
		.data_addr_ok(data_addr_ok),
		.data_data_ok(data_data_ok),
		.data_enable_miss_back(denable_miss),
		.data_waddr_ok(data_waddr_ok),
		.data_uncache_ok(~uncache_full),
		.read_queue_index(read_queue_index),
		.uncache_data_ok(ucache_data_ok),
		.mshr_data_ok(long_data_ok),
		.mshr_queue_index(long_queue_index),
		.mshr_data(long_data),

		.uncache_req(uncache_req),
		.uncache_wr(uncache_wr),
		.uncache_wstrb(uncache_wstrb),
		.uncache_addr(uncache_addr),
		.uncache_queue_index(uncache_queue_index),
		.uncache_data(uncache_data),

		.icache_ready(icache_ready),
		.dcache_ready(dcache_ready),
		.cache_valid(cache_valid),
		.cacheop(cacheop),
		.cache_addr(cache_addr),

		.tlb_entry_lo0_in(tlb_entry_lo0),
		.tlb_entry_lo1_in(tlb_entry_lo1),
		.tlb_page_mask_in(tlb_page_mask),
		.tlb_entry_hi_in(tlb_entry_hi),
		.tlb_index_in(tlb_index),
		.cp0_tlb_type(cp0_tlb_type),
		.cp0_tlb_inst_en(cp0_tlb_inst_en),
		.cp0_entry_hi_out(cp0_entry_hi), 
		.cp0_page_mask_out(cp0_page_mask),
		.cp0_entry_lo0_out(cp0_entry_lo0),
		.cp0_entry_lo1_out(cp0_entry_lo1),
		.cp0_index_out(cp0_index),
		.cp0_random_out(cp0_random),
		.cp0_taglo_out(cp0_taglo),
		.kseg0_uncache(kseg0_uncache)
    );

	TLB tlb(
		.clk(aclk),
		.resetn(cpu_rst_n),
		.inst_vaddr({isearch_tag, inst_vaddr[`ICACHE_INDEX+`ICACHE_OFFSET-1: 0]}),
		.rdata_vaddr({dsearch_tag, data_vaddr[`DCACHE_INDEX+`DCACHE_OFFSET-1: 0]}),
		.vwtag(vwtag),
		.inst_paddr(inst_paddr),
		.rdata_paddr(data_paddr),
		.pwtag(pwtag),
		.iuncache(tlb_iuncache),
		.druncache(tlb_druncache),
		.dwuncache(tlb_dwuncache),

		.inst_tlb_refill(inst_tlb_refill), 
		.inst_tlb_invalid(inst_tlb_invalid),
		.rdata_tlb_refill(rdata_tlb_refill), 
		.rdata_tlb_invalid(rdata_tlb_invalid), 
		.wdata_tlb_refill(wdata_tlb_refill),
		.wdata_tlb_invalid(wdata_tlb_invalid),
		.data_tlb_modify(data_tlb_modify),

		.TLBP	(cp0_tlb_inst_en ? cp0_tlb_type[0] : 0),
		.TLBR	(cp0_tlb_inst_en ? cp0_tlb_type[1] : 0),
		.TLBWI	(cp0_tlb_inst_en ? cp0_tlb_type[2] : 0),
		.TLBWR	(cp0_tlb_inst_en ? cp0_tlb_type[3] : 0),

		.EntryHi_in(cp0_entry_hi),
		.PageMask_in(cp0_page_mask),
		.EntryLo0_in(cp0_entry_lo0),
		.EntryLo1_in(cp0_entry_lo1),
		.Index_in(cp0_index),
		.Random_in(cp0_random),
		.kseg0_uncache(kseg0_uncache),

		.EntryHi_out(tlb_entry_hi),
		.PageMask_out(tlb_page_mask),
		.EntryLo0_out(tlb_entry_lo0),
		.EntryLo1_out(tlb_entry_lo1),
		.Index_out(tlb_index)
	);
    
endmodule